﻿using System;
using System.Collections.Generic;
using System.Linq;
using TuxedoLib;

namespace SpaceSquirrel.SpecialLevelStuff
{
	public class BalloonPopping : SpecialLevel
	{
		private string id;
		public bool Done { get; private set; }
		private Dictionary<string, Tile> balloonCoords = new Dictionary<string, Tile>();

		public BalloonPopping(PlayScene scene, string id) : base(scene)
		{
			this.id = id;
			this.HasUpdate = true;
			this.HasPostInit = true;
			this.Done = false;

			if (id.StartsWith("water"))
			{
				int rows = scene.rows;
				int cols = scene.cols;
				for (int y = 0; y < rows; ++y)
				{
					for (int x = 0; x < cols; ++x)
					{
						if (scene.Tiles[x][y].isBalloon)
						{
							this.balloonCoords[x + "," + y] = scene.Tiles[x][y];
						}
					}
				}
			}
		}

		public override void Update()
		{
			if (!this.Done)
			{
				Sprite player = this.scene.Player;
				int tx = player.x / 16;
				int ty = player.y / 16;

				// lol
				if (this.id == "water1" && ty > 18) return;
				if (this.id == "water4" && ty < 18) return;

				Tile tile;
				if (this.balloonCoords.TryGetValue(tx + "," + ty, out tile))
				{
					this.ApplyOverlayAndSaveContext(true, new int[] { tx + tile.primaryBalloonOffset[0], ty + tile.primaryBalloonOffset[1] });
				}

			}
		}

		public override void PostInit()
		{
			// yeah, there's a better way to do this...
			Context ctx = this.context;
			bool applyOverlay =
				(this.id == "water1" && ctx.BalloonA) ||
				(this.id == "water2" && ctx.BalloonB) ||
				(this.id == "water3" && ctx.BalloonC) ||
				(this.id == "water4" && ctx.BalloonD) ||
				(this.id == "lava1" && ctx.VolcanoA) ||
				(this.id == "lava2" && ctx.VolcanoB) ||
				(this.id == "lava3" && ctx.VolcanoC);

			if (applyOverlay)
			{
				this.ApplyOverlayAndSaveContext(false, null);
			}
		}

		// pass in coords separately
		private void ApplyOverlayAndSaveContext(bool showPop, int[] balloonLoc)
		{
			if (this.Done) return;

			string overlayMapName = this.scene.OverlayTriggers[this.id]; // # Go ahead and crash if not present. Game is busted at this point anyway.

			PlayScene overlay = new PlayScene(overlayMapName, 0, 0, new Context());
			PlayScene original = this.scene;

			// ummmmmm....
			// this was a typo in the original that I'll go ahead and preserve for the sake of preventing any unknown flux.
			// This should be min(original.cols, overlay.cols), etc

			int width = Math.Min(original.cols, original.cols);
			int height = Math.Min(original.rows, original.rows);
			Tile[][] grid = original.Tiles;
			Tile[][] overlayTiles = overlay.Tiles;

			for (int y = 0; y < height; ++y)
			{
				for (int x = 0; x < width; ++x)
				{
					if (overlay.Tiles[x][y].originalTemplates.Length > 0)
					{
						TileTemplate[] templates = Util.ArrayConcat<TileTemplate>(grid[x][y].originalTemplates, overlay.Tiles[x][y].originalTemplates);
						grid[x][y] = new Tile(templates, x, y);
					}
				}
			}

			if (this.id == "water1") this.context.BalloonA = true;
			else if (this.id == "water2") this.context.BalloonB = true;
			else if (this.id == "water3") this.context.BalloonC = true;
			else if (this.id == "water4") this.context.BalloonD = true;

			this.Done = true;

			if (showPop)
			{
				SoundManager.PlayNoise("water_pop");
				
				original.Sprites.Add(
					new Sprite("waterpop", balloonLoc[0] * 16 + 8, balloonLoc[1] * 16 + 8));

				if (this.context.BalloonA && this.context.BalloonB && this.context.BalloonC && this.context.BalloonD)
				{
					this.scene.Next = new DialogScene(this.scene, "WaterDone", true, false, false);
				}
			}
		}
	}
}
